package com.kadron.favorites;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.kadron.common.KeyValue;
import com.kadron.creator.KItemModelCreator;
import com.kadron.dao.KUserFavoritesDAO;
import com.kadron.entity.Item;
import com.kadron.paging.KRowParent;
import com.kadron.paging.KRowService;

public class KFavoriteUserRowService implements KRowService {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5862117516679924629L;
	
	private KFavoriteUserModelCreator creator;
	private KUserFavoritesDAO userFavoritesDAO;
	private KUserFacoriteSearch search;
	
	public KFavoriteUserRowService(KFavoriteUserModelCreator creator, KUserFacoriteSearch search, KUserFavoritesDAO userFavoritesDAO) {
		super();
		this.creator = creator;
		this.search = search;
		this.userFavoritesDAO = userFavoritesDAO;
	}

	@SuppressWarnings("unchecked")
	public void getModels(KRowParent parent, int first, int max) {
		Query query = createQuery(false);
		query.setFirstResult(first);
		query.setMaxResults(max);
		List<Long> itemIds = query.getResultList();
		doCreate(parent, itemIds);
	}

	public KFavoriteUserModel getItemById(Long id, KItemModelCreator creator) {
		return getCreator().create(id);
	}

	public long getCount(KRowParent parent) {
		Query query = createQuery(true);
		Long countNumber = (Long) query.getSingleResult();
		long count = (countNumber == null) ? 0 : countNumber.intValue();
		parent.getModelContainer().setCount(count);
		return  count;
	}

	public boolean hasItemWithId(Long id) {
		return userFavoritesDAO.exists(id, Item.class);
	}

	public KFavoriteUserModelCreator getCreator() {
		return creator;
	}
	
	public KUserFacoriteSearch getSearch() {
		return search;
	}

	public void setSearch(KUserFacoriteSearch search) {
		this.search = search;
	}

	@Override
	public void getAllModels(KRowParent parent) throws UnsupportedOperationException {
		throw new UnsupportedOperationException();
	}

	@Override
	public KRowParent doCreate(KRowParent parent, List<Long> rows) {
		parent.getModelContainer().getModels().clear();
		for (Long rowId : rows) {
			KFavoriteUserModel model = null;
			String key = rowId.toString();
			if (!parent.getModelContainer().getWrappedKeys().contains(key)) {
				model = creator.create(rowId);
			} else {
				model = (KFavoriteUserModel) parent.getModelContainer().getWrappedData().get(key);
			}
			parent.getModelContainer().getModels().add(model);
			parent.getModelContainer().wrapp(key, model);
		}
		parent.getModelContainer().initPages();
		return parent;
	}
	
	private final Query createQuery(boolean isCount) {
		EntityManager em = userFavoritesDAO.getEntityManager();
		Set<KeyValue> params = new HashSet<KeyValue>();
		StringBuilder builder = new StringBuilder("SELECT ");
		if (isCount) {			
			builder.append(" COUNT(e.id) ");
		} else {			
			builder.append(" e.id ");
		}
		builder.append(" FROM UserFavorites e WHERE e.id > 0 ");
		if (search.getUserId() > 0) {
			builder.append(" AND e.user.id = :user_id ");			
			params.add(new KeyValue("user_id", search.getUserId()));
		} 
		if (search.getItemId() > 0) {
			builder.append(" AND e.item.id = :item_id ");			
			params.add(new KeyValue("item_id", search.getItemId()));
		} 
		if (!isCount) {
			builder.append(" ORDER BY e.id DESC");
		}
		Query query = em.createQuery(builder.toString());
		for (KeyValue p : params) {
			query.setParameter(p.getKey(), p.getValue());
		}
		return query;
	}

}
